<template>
  <div>
    <div class="spece" v-for="(i, d) in goods_spec_title" :key="d">
      <div>规格{{ d + 1 }}：</div>
      <div class="spece_box">
        <div class="spece_input">
          <q-input
            outlined
            dense
            v-model="i.spec_name"
            type="text"
            ref="specValueInput"
            style="max-width: 300px"
            @focus="attrFocus(i.spec_name)"
            @blur="attrBlur(i.spec_name)"
          />
          <q-btn
            flat
            round
            dense
            class="q-mx-xs"
            color="grey"
            icon="close"
            @click="removeSpec(d)"
          />
          <!-- <q-btn
            flat
            round
            dense
            class="q-mx-xs"
            color="green"
            icon="check"
            @click="checkSpec(d)"
          /> -->
        </div>
        <div class="tag_box">
          <el-tag
            class="mx-1"
            :closable="goods_spec_title[d].spec_value.length > 1"
            type=""
            v-for="(tag, tagIndex) in i.spec_value"
            :key="tagIndex"
            @close="
              tagClose(d, tagIndex, i.spec_name, i.spec_value[tagIndex].value)
            "
            style="margin-right: 5px; margin-bottom: 5px"
          >
            {{ tag.value }}
          </el-tag>
        </div>

        <div class="cursor-pointer" v-if="i.spec_name !== ''">
          <div class="spece_value">+添加规格值</div>
          <q-popup-edit v-model="setValue" @hide="setHide" ref="popupedit">
            <template v-slot="{ emitValue }">
              <q-input
                autofocus
                dense
                v-model="setValue"
                hint="请输入规格值，按回车键确认"
                @input="emitValue"
                @keyup.enter="setSpeceValue(i.spec_name, setValue, d)"
              >
                <template v-slot:after>
                  <q-btn
                    flat
                    dense
                    color="positive"
                    icon="check_circle"
                    class="after_btn"
                    @click.stop="setSpeceValue(i.spec_name, setValue, d)"
                  />
                </template>
              </q-input>
            </template>
          </q-popup-edit>
        </div>
      </div>
    </div>
    <div class="q-pa-md">
      <div class="cursor-pointer" style="width: 35%">
        <q-btn
          class="btn_bottom color-primary"
          color="primary"
          label="添加规格"
          unelevated
        />
        <q-popup-edit
          v-model="add_value"
          @hide="setHideBool"
          ref="popupeditBool"
        >
          <template v-slot="{ emitValue }">
            <q-input
              autofocus
              dense
              v-model="add_value"
              hint="请输入规格名称，按回车键确认"
              @input="emitValue"
              @keyup.enter="addSpec()"
            >
              <template v-slot:after>
                <q-btn
                  flat
                  dense
                  color="positive"
                  icon="check_circle"
                  class="after_btn"
                  @click.stop="addSpec()"
                />
              </template>
            </q-input>
          </template>
        </q-popup-edit>
      </div>
    </div>

    <div class="test">
      <q-card class="q-mt-lg q-pt-md q-pb-lg">
        <div class="q-pt-sm q-px-lg">
          <el-table :data="table_data" border :span-method="mergeRowComputed">
            <el-table-column
              v-for="(specItem, itemIndex) in goods_spec_title"
              :key="itemIndex"
              :label="specItem.spec_name"
              :prop="specItem.spec_name"
            >
            </el-table-column>
            <el-table-column label="价格" prop="price">
              <template #default="scope">
                <el-input
                  v-model="scope.row.price"
                  :ref="'priceValueInput' + [[scope.$index]]"
                ></el-input>
              </template>
            </el-table-column>
            <el-table-column label="划线价格" prop="market_price">
              <template #default="scope">
                <el-input v-model="scope.row.market_price"></el-input>
              </template>
            </el-table-column>
            <el-table-column label="成本价" prop="cost_price">
              <template #default="scope">
                <el-input v-model="scope.row.cost_price"></el-input>
              </template>
            </el-table-column>
            <el-table-column label="折扣价" prop="discount_price">
              <template #default="scope">
                <el-input
                  v-model="scope.row.discount_price"
                  :ref="'discount_priceValueInput' + [[scope.$index]]"
                ></el-input>
              </template>
            </el-table-column>
            <el-table-column label="库存" prop="stock">
              <template #default="scope">
                <el-input v-model="scope.row.stock"></el-input>
              </template>
            </el-table-column>
            <el-table-column label="限购数量" prop="max_buy">
              <template #default="scope">
                <el-input v-model="scope.row.max_buy"></el-input>
              </template>
            </el-table-column>
            <el-table-column label="最低购买" prop="min_buy">
              <template #default="scope">
                <el-input v-model="scope.row.min_buy"></el-input>
              </template>
            </el-table-column>
            <el-table-column label="推荐方式" prop="recommend_way">
              <template #default="scope">
                <el-select
                  v-model="scope.row.recommend_way"
                  placeholder="请选择推荐方式"
                >
                  <el-option
                    v-for="item in optionsWay"
                    :key="item.value"
                    :label="item.label"
                    :value="item.value"
                  />
                </el-select>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </q-card>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { useQuasar } from 'quasar';

interface Props {
  goods_title?: any;
  table?: any;
}
const props = withDefaults(defineProps<Props>(), {});
const emit = defineEmits(['Updatetable']);

const tableHeaderList: any = ref([
  'price',
  'market_price',
  'cost_price',
  'discount_price',
  'stock',
  'max_buy',
  'min_buy',
  'recommend_way',
]); // 表格列
const setValue = ref('');
const popupedit = ref();
const popupeditBool = ref();
const specValueInput = ref();
const old_attr: any = ref('');
const specCounts = ref(0);
const sp_id = ref(-1); // 新增table_data的id
const sc_id = ref(-1); // 新增规格名的id
const add_value = ref(''); // 添加属性的input
const $q = useQuasar();
const optionsWay = ref([
  {
    value: 0,
    label: '无',
  },
  {
    value: 1,
    label: '新品',
  },
  {
    value: 2,
    label: '精品',
  },
  {
    value: 3,
    label: '推荐',
  },
]);

const goods_spec_title: any = computed({
  set(value: any) {
    // emit('update:search', value);
  },
  get() {
    console.log('props.search', props.goods_title);
    return props.goods_title;
  },
});
const table_data: any = computed({
  set(value: any) {
    // emit('update:table', value);
  },
  get() {
    console.log('props.table', props.table);
    return props.table;
  },
});
const selectedAttr: any = computed({
  set(value: any) {
    // emit('update:form', value);
  },
  get() {
    return goods_spec_title.value.map((x: any) => x.spec_name);
  },
});

onMounted(() => {
  if (goods_spec_title.value.length > 0) {
    //回显
    generateTableColumn();
  }
});

const setHide = () => {
  console.log('setHide');
  setValue.value = '';
};
const setHideBool = () => {
  console.log('setHideBool');
  add_value.value = '';
};
const setSpeceValue = (curr_attr: any, newVal: any, specItemIndex: any) => {
  console.log('setSpeceValue', setValue.value, newVal);
  if (curr_attr === '') return;
  if (setValue.value !== '') {
    goods_spec_title.value[specItemIndex].spec_value.push({
      value: setValue.value,
    });
  }
  let value_num = goods_spec_title.value[specItemIndex].spec_value.filter(
    (item: any) => item.value == newVal
  );
  if (value_num.length > 1) {
    $q.notify({
      type: 'warning',
      position: 'top',
      message: '规格值不能重复',
    });
    goods_spec_title.value[specItemIndex].spec_value.splice(
      goods_spec_title.value[specItemIndex].spec_value.length - 1,
      1
    );

    return;
  }

  //  这里根据规格生成的笛卡尔积计算出table中需要改变的行索引 ( 包含新增和修改 )
  let cartesian_arr = generateBaseData(goods_spec_title.value);
  let change_idx_arr: any = []; // 需要被改变的行的索引
  for (let i in cartesian_arr) {
    if (cartesian_arr[i][curr_attr] === newVal) change_idx_arr.push(Number(i));
  }
  console.log('change_idx_arr', curr_attr, cartesian_arr, change_idx_arr);

  // 新的表格应该有的长度与现有的表格长度比较, 区分新增还是修改
  let length_arr = goods_spec_title.value.map((x: any) => x.spec_value.length);
  let new_table_length = length_arr.reduce(
    (acc: any, curr_item: any) => acc * curr_item
  ); // 新的表格数据长度 求乘积
  let old_table_length = table_data.value.length; // 旧的表格数据长度

  specCounts.value = new_table_length;
  for (var i = 0; i < goods_spec_title.value.length; i++) {
    popupedit.value[i].hide();
  }
  // 如果是修改
  if (new_table_length === old_table_length) {
    console.log('修改。。');
    table_data.value.forEach((item: any, index: any) => {
      if (change_idx_arr.includes(index))
        table_data.value[index][curr_attr] = newVal;
    });
    return;
  }

  // 如果是新增
  if (new_table_length > old_table_length) {
    console.log('新增。。');

    // 得到当前属性的当前值和其他规格的 goodsSpecs, 构造新的表格数据
    let other_sku_arr = goods_spec_title.value.map((item: any) => {
      if (item.spec_name !== curr_attr) return item;
      else {
        return {
          spec_name: item.spec_name,
          spec_value: [
            {
              value: newVal,
            },
          ],
        };
      }
    });
    // 得到新增的表格数据
    let ready_map = generateBaseData(other_sku_arr);
    let new_table_data = mergeTableData(ready_map);

    change_idx_arr.forEach((item_idx: any, index: any) => {
      table_data.value.splice(item_idx, 0, new_table_data[index]);
    });

    table_data.value.reverse().reverse();
  }
  console.log('测试得到数据表', table_data.value);
};
const removeSpec = (index: any) => {
  console.log('removeSpec');
  goods_spec_title.value.splice(index, 1);

  // 生成处理表头数据和表格数据
  generateTableColumn();
  traverseSku();
  // goods_spec_title.value.splice(index, 1);
};
const checkSpec = (index: any) => {
  console.log('checkSpec');
};
const tagClose = (
  specItemIndex: any,
  valueItemIndex: any,
  attr_name: any,
  attr_val: any
) => {
  console.log('tagClose');
  // goods_spec_title.value[d].spec_value.splice(index, 1);
  goods_spec_title.value[specItemIndex]['spec_value'].splice(valueItemIndex, 1);

  // 删除table行
  let data_length = table_data.value.length;
  for (let i = 0; i < data_length; i++) {
    if (table_data.value[i][attr_name] == attr_val) {
      table_data.value.splice(i, 1);
      i = i - 1;
      data_length = data_length - 1;
    }
  }

  specCounts.value = table_data.value.length;
};
const addSpec = () => {
  console.log('addSpec');
  //goods_spec_title下spec_value如果有一个长等于0，则不能新增规格
  let spec_value_length = goods_spec_title.value.map(
    (item: any) => item.spec_value.length
  );
  if (spec_value_length.includes(0)) {
    $q.notify({
      type: 'warning',
      position: 'top',
      message: '规格值不能为空,请先添加规格值',
    });
    return;
  }
  if (!add_value.value) return;
  if (selectedAttr.value.includes(add_value.value)) {
    $q.notify({
      type: 'warning',
      position: 'top',
      message: '不能添加相同规格名',
    });
    return;
  }
  sc_id.value++;
  goods_spec_title.value.push({
    id: 'SC' + sc_id.value,
    spec_name: add_value.value,
    spec_value: [
      // {
      //   id: 'SV0&' + 'SC' + sc_id.value,
      //   specid: 'SC' + sc_id.value,
      //   value: '',
      // },
    ],
  });
  // 生成处理表头数据和表格数据
  generateTableColumn();
  traverseSku();

  popupeditBool.value.hide();
  add_value.value = '';
};

// 合并单元格
const mergeRowComputed = ({ row, column, rowIndex, columnIndex }) => {
  if (columnIndex == 0) {
    let key_0 = column.label;
    let first_idx = table_data.value.findIndex(
      (x: any) => x[key_0] == row[key_0]
    );
    const calcSameLength = () =>
      table_data.value.filter((x: any) => x[key_0] == row[key_0]).length;
    const first_column_rule =
      rowIndex == first_idx ? [calcSameLength(), 1] : [0, 0];
    return first_column_rule;
  } else {
    // 表格数据的每一项,
    const callBacks: any = (table_item: any, start_idx = 0) => {
      if (columnIndex < start_idx) return true;
      let curr_key = tableHeaderList.value[start_idx];
      return (
        table_item[curr_key] === row[curr_key] &&
        callBacks(table_item, ++start_idx)
      );
    };
    let first_idx = table_data.value.findIndex((x: any) => callBacks(x));
    const calcSameLength = () =>
      table_data.value.filter((x: any) => callBacks(x)).length;
    return rowIndex == first_idx ? [calcSameLength(), 1] : [0, 0];
  }
};
// 属性获得焦点时 得到旧的值 存一下
const attrFocus = (oldVal: any) => {
  old_attr.value = oldVal;
};
// 属性失去焦点时
const attrBlur = (newVal: any) => {
  console.log('attrBlur');
  // 如果 '新值等于旧值' 或者 '空' 什么也不做
  if (newVal === old_attr.value || newVal === '') {
    console.log("如果 '新值等于旧值' 或者 '空' 什么也不做");
    return;
  }

  // 生成处理表头数据和表格数据
  generateTableColumn();
  traverseSku();
};
// 根据 `this.tableColumnList.goodsSpecs` 生成表格列, `tableHeaderList` 用于 el-table-column 的 v-for
const generateTableColumn = () => {
  tableHeaderList.value = goods_spec_title.value
    .map((x: any) => x.spec_name)
    .concat([
      'price',
      'market_price',
      'cost_price',
      'discount_price',
      'stock',
      'max_buy',
      'min_buy',
      'recommend_way',
    ]);
};
// 遍历 `goodsSpecs` 生成表格数据
const traverseSku = () => {
  let ready_map = generateBaseData(goods_spec_title.value);
  console.log('ready_map', ready_map, table_data.value);
  //直接修改table_data的值
  emit('Updatetable', mergeTableData(ready_map));
  // table_data.value = mergeTableData(ready_map);
  setTimeout(() => {
    console.log(
      'table_data.value',
      table_data.value,
      mergeTableData(ready_map)
    );
  }, 1000);
  specCounts.value = table_data.value.length;
  console.log('specCounts.value', specCounts.value);
};
// 合并 goodsSpecs 与 '现价', '库存', '市场价格' , 返回整个表格数据数组
const mergeTableData = (arr: any) => {
  return arr.map((item: any) => {
    sp_id.value++;
    return {
      ...item,
      id: 'SP' + sp_id.value,
      price: '',
      market_price: '',
      cost_price: '',
      discount_price: '',
      stock: '',
      max_buy: '',
      min_buy: '',
      recommend_way: 0,
    };
  });
};
// 重新实现笛卡尔积  入参是: this.tableColumnList.goodsSpecs 传入的数组 '为空', '长度为1', '长度大于1' 三种情况 分别处理
const generateBaseData = (arr: any) => {
  if (arr.length === 0) return [];
  if (arr.length === 1) {
    let [item_spec] = arr;
    return item_spec.spec_value.map((x: any) => {
      return {
        [item_spec.spec_name]: x.value,
      };
    });
  }
  if (arr.length >= 1) {
    return arr.reduce((accumulator: any, spec_item: any) => {
      // accumulator判断之前的数据是  整合的规格数组还是单个规格项
      let acc_value_list = Array.isArray(accumulator.spec_value)
        ? accumulator.spec_value
        : accumulator;
      // 获取当前项的valueList
      let item_value_list = spec_item.spec_value;
      let result = [];
      for (let i in acc_value_list) {
        for (let j in item_value_list) {
          // 计算每种组合
          let temp_data: any = {};
          if (!acc_value_list[i].value) {
            // accumulator不是Array的情况
            temp_data = {
              ...acc_value_list[i],
              [spec_item.spec_name]: item_value_list[j].value,
            };

            // 否则如果是单个规格项
          } else {
            temp_data[accumulator.spec_name] = acc_value_list[i].value;
            temp_data[spec_item.spec_name] = item_value_list[j].value;
          }
          result.push(temp_data);
        }
      }
      return result;
    });
  }
};
onMounted(() => {
  console.log('重新加载');
});
</script>
<style scoped lang="scss">
.spece {
  display: flex;
  padding: 10px;
  .spece_box {
    display: flex;
    flex-direction: column;
    .spece_input {
      display: flex;
      align-items: center;
    }
    .tag_box {
      padding: 10px 0;
      max-width: 250px;
    }
  }
}
.spece_value {
  color: #1890ff;
  cursor: pointer;
  margin-top: 8px;
}
// ::v-deep(.q-btn:before) {
//   display: flex;
//   align-items: center;
//   justify-content: center;
// }\
::v-deep(.my-special-class) {
  height: 48px;
  background: #fafafa;
}
::v-deep(.my-special-class th) {
  font-size: 16px;
}
.after_btn {
  display: none;
}
.test {
  max-width: calc(100vw - 62px);
}

@media screen and (max-width: 780px) {
  // .test {
  //   max-height: 400px;
  // }
  .after_btn {
    display: block;
  }
}
</style>
